home *** CD-ROM | disk | FTP | other *** search
- /*----------------------------------------------------------------------*/
- /* */
- /* Sample usage of scalable font fractional spacing and kerning. */
- /* */
- /* This file demonstrates how scalable fonts can be used in the */
- /* DESQview/X environment. It emphasises how fractional spacing */
- /* and kerning are performed. */
- /* */
- /*----------------------------------------------------------------------*/
-
- #include <stdio.h>
- #if defined(_HIGHC_)
- #include <stdlib.h>
- #endif
- #include <X11/Xmd.h>
- #include <X11/X.h>
- #include <X11/Xos.h>
- #include <X11/Xlib.h>
- #include <X11/Xutil.h>
- #include <X11/Xatom.h>
-
-
-
- typedef struct KERNPAIRtag
- {
- char chLeft;
- char chRight;
- INT32 xKernOffset;
- } KERNPAIR;
-
-
- Display *dpy;
- int screen;
- Window root;
- GC gcBase;
- Window winMain;
- KERNPAIR *pKernBase;
- XFontStruct *xfn;
-
-
- /*----------------------------------------------------------------------*/
- /* BASIC X OPERATIONS */
- /*----------------------------------------------------------------------*/
-
- main ()
- {
- XSetWindowAttributes xswa;
-
- dpy = XOpenDisplay (NULL);
- screen = DefaultScreen(dpy);
- root = RootWindow(dpy,screen);
- gcBase = DefaultGC(dpy,screen);
- winMain = XCreateSimpleWindow (dpy, root, 0, 0, 500, 100, 0, 0L, 15L);
- xswa.event_mask = ExposureMask;
- XChangeWindowAttributes (dpy, winMain, CWEventMask, &xswa);
- XMapWindow (dpy, winMain);
- InitText ("Times Roman-Medium-R", 24);
-
- while (1)
- {
- XEvent xe;
-
- XNextEvent (dpy,&xe);
- switch (xe.type)
- {
- case Expose:
- DrawText (10, 50, "This is the string to be printed.");
- break;
-
- case DestroyNotify:
- ClearText ();
- break;
- }
- }
- }
-
-
- /*----------------------------------------------------------------------*/
- /* SAMPLE CODE FOR FRACTIONAL SPACING AND KERNING */
- /*----------------------------------------------------------------------*/
-
-
- /*----------------------------------------------------------------------*/
- /* LOAD FONT AND READ KERNING PAIRS */
- /*----------------------------------------------------------------------*/
-
- InitText (char *pszFont, int PointSize)
- {
- char szName[256];
- int xRes;
- int yRes;
- Atom atomKernLabel, atomKernVar;
- XGCValues values;
- KERNPAIR *pKern;
- Atom atomType;
- int iFormat;
- long cItems;
- long bytes_after;
- char *pProp;
- char *pPropBase;
- int cProps;
-
- xRes = 75;
- yRes = 75;
- sprintf (szName, "-Adobe-%s-Normal--*-%d-%d-%d-*-*-*-Adobe",
- pszFont, PointSize*10, xRes, yRes);
-
- xfn = XLoadQueryFont (dpy, szName); /* load the font */
- if (xfn)
- {
- values.font = xfn->fid;
- XChangeGC (dpy, gcBase, GCFont, &values);
-
- /* Now we want to grab the kerning pairs. This is done by looking at the */
- /* font property 'KERNING_PAIRS' to find the root windows property name. */
- /* The root property is next examined to extract the needed pairs. The */
- /* pairs are transferred into an array. */
-
- atomKernLabel = XInternAtom (dpy, "KERNING_PAIRS", 0);/* enumerate prop */
- XGetFontProperty (xfn, atomKernLabel, &atomKernVar); /* grab root name */
- XGetWindowProperty (dpy, root, atomKernVar, 0, 8192, /* get the info */
- False, AnyPropertyType, &atomType, &iFormat, &cItems, &bytes_after, &pProp);
- pPropBase = pProp;
- cProps = *(INT16 *)pProp; pProp+=2; /* get number of properties */
- pKern = (KERNPAIR *)malloc (sizeof(KERNPAIR) * (cProps+1));
- pKernBase = pKern;
- while (cProps--)
- {
- pKern->chLeft = *pProp++; /* left character in pair */
- pKern->chRight = *pProp++; /* right character in pair */
- pKern->xKernOffset = (INT32)(*(INT16 *)pProp) + ((INT32)(*(INT16 *)(pProp+2)))*65536L;
- pProp += 4;
- pKern++;
- }
- pKern->chLeft = 0; /* mark end of table */
- pKern->chRight = 0;
- pKern->xKernOffset = 0;
-
- XFree (pPropBase); /* we are done with the data */
- }
- }
-
-
- /*----------------------------------------------------------------------*/
- /* UNLOAD FONT AND KERNING PAIRS */
- /*----------------------------------------------------------------------*/
-
- ClearText ()
- {
- free (pKernBase); /* free kerning stuff */
- XFreeFont (dpy, xfn); /* get rid of font */
- }
-
- /*----------------------------------------------------------------------*/
- /* FIND PAIR OF CHARACTERS IN KERNING ARRAY */
- /*----------------------------------------------------------------------*/
-
- /* This routine just does a simple sequential search to find the kerning */
- /* pair. A better implementation would be to sort the array and perform */
- /* binary searches. */
-
- INT32 LookupKern (char chLeft, char chRight)
- {
- KERNPAIR *pKern;
-
- pKern = pKernBase;
- while (pKern->chLeft)
- {
- if ((pKern->chLeft == chLeft) && (pKern->chRight == chRight))
- return (pKern->xKernOffset); /* return delta */
- pKern++;
- }
- return (0L); /* no pair -> delta = 0 */
- }
-
- /*----------------------------------------------------------------------*/
- /* OUTPUT ONE LINE OF TEXT WITH KERNING + FRACTIONAL SPACING */
- /*----------------------------------------------------------------------*/
-
- /* This routine performs fractional spacing and kering as described */
- /* in the documentation. A series of XTextItem text chunks is output */
- /* with delta "corrections" to compensate for the difference between */
- /* rouded integer spacing and fractional spacing. */
-
- DrawText (int xPos, int yPos, char *pszText)
- {
- char chPrev; /* previous character */
- XTextItem ati[100]; /* XTextItem array for cummulation */
- int cItems; /* count of XTextItem entries */
- INT16 xPosRound; /* running x position as rounded integer */
- INT32 xPosFixed; /* running x position as 16.16 fixed nota'n */
- char *pszBase; /* running pointer to base of text chunk */
- INT16 DeltaInt; /* rounded integer character width */
- INT16 DeltaFrac; /* signed fractional part of character wid. */
- INT16 xPosCheck; /* variable fo comparing widths */
- int cChars; /* number of charcters in XTextItem entry */
-
- cChars = 0; /* initialize some stuff */
- chPrev = 0;
- xPosRound = 0;
- xPosFixed = 0;
- cItems = 0;
- pszBase = pszText;
- ati[0].delta = 0;
-
- while (*pszText)
- {
- xPosFixed += LookupKern (chPrev, *pszText); /* make kerning adjustment */
- xPosCheck = (INT16)((xPosFixed+32768L)>>16); /* get round (16.16) */
- if (xPosCheck != xPosRound) /* is "correction" necessary? */
- {
- ati[cItems].chars = pszBase; /* sequence of characters to output */
- ati[cItems].nchars = cChars; /* number of characters to output */
- ati[cItems+1].delta = xPosCheck - xPosRound; /* how much of an adjmnt */
- ati[cItems].font = 0; /* we want to use the current font */
- xPosRound = xPosCheck; /* "correct" the running rounded x pos */
- pszBase = pszText; /* next text chunk will start here */
- cChars = 0; /* reset count for next chunk */
- cItems++; /* increment XTextItem counter */
- }
- DeltaInt = xfn->per_char[(INT16)*pszText - xfn->min_char_or_byte2].width;
- DeltaFrac = xfn->per_char[(INT16)*pszText - xfn->min_char_or_byte2].attributes;
- xPosRound += DeltaInt; /* update running x counters */
- xPosFixed += (((INT32)DeltaInt)<<16) + (INT32)DeltaFrac;
- cChars++; /* note that (INT32)DeltaFrac is signed */
- chPrev = *pszText++; /* so that it can both lower and raise DeltaInt */
- }
- ati[cItems].chars = pszBase; /* final XTextItem chunk */
- ati[cItems].nchars = cChars;
- ati[cItems].font = 0;
- cItems++;
-
- /* now, we actually print out the results of the above calculations */
-
- XDrawText (dpy, winMain, gcBase, xPos, yPos, ati, cItems);
- }